#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<mpi.h>
#include<sys/time.h>
#include<math.h>

char letra = '0';//mto utilizada para pegar cada caracter lido do arquivo
char* palavra;//palavra, pteste,nroletras,nrofrases,tamstring e x e frase foram usados para testes durantea implementacao
int nroletras = 0;
int partitionsize = 5000;//as porcentagens estao erradas pois eh o numero total de palavras pelo numero de palavras da frase
int tamstring;
int j;
char letrafrase;//mesma funcionalidade de letra
char* subfrase;
int ascii;
int tamanhodicionario = 1000000;//comentei dicionario para testar mais rapido
int indicedicionario = 0;
char* dicionario;
char* copia;
int base = 0;
int tag;

int stat;//variaveis do paralelo
int nronos = 0;
int rank = 0;

struct timeval tvBegin, tvMarco;//variaveis de tempo
double porcent20 = 0.0;//doubles para calcular a porcentagem
double porcent40 = 0.0;
double porcent60 = 0.0;
double porcent80 = 0.0;
double porcent85 = 0.0;
double porcent100 = 0.0;

int numpal = 0;//numero total de palavras
int aux = 0;//auxiliar que recebe o numero acima e eh decrementada para que possa-se calcular a porcentagem

struct tvetorletra{
  char* letra;//vetor de uma letra de a-z
  int tamanho;//tamanho do vetor acima
};

typedef struct tvetorletra vetorletra;

vetorletra* duas;//eesas quatro variaveis contem todos os vetores de a-z com duas, tres, quatro e cinco letras respectivamente,
vetorletra* tres;//assim temos divisao pela letra inicial e pelo tamanho da palvra
vetorletra* quatro;
vetorletra* cinco;

int nropalavrasduas = 0;//numeros de palavras de duas, tres, quatro e cinco letras que servem para interromeper os lacos dos passeio quando chegam a zero
int nropalavrastres = 0;
int nropalavrasquatro = 0;
int nropalavrascinco = 0;

int contadortres = 0;//contadortres, contadorquatro e contadorcinco contam ateh 100 para que um send possa ser enviado avisando q essa quantidade de palavras foi gerada
int contadorquatro = 0;
int contadorcinco = 0;

int cont123 = 0;//auxiliar como o do caso acima
int flag = 1;//serve como auxiliar no case de porcentagem a ser impressa

int main(int argc, char** argv)
{
    if(rank ==0){
      gettimeofday(&tvBegin, NULL);
    }

    MPI_Status stat;
    if( MPI_Init(&argc,&argv) == MPI_SUCCESS)
      printf("\nIniciou");
    else
      printf("\n Nao Iniciou");
    if ( MPI_Comm_rank(MPI_COMM_WORLD, &rank) == MPI_ERR_COMM){
      printf("##########Esta mensagem nao deve aparecer, e caso apareca o programa nao vai funcionar##############");
    }

    MPI_Comm_size(MPI_COMM_WORLD,&nronos);
    if( (rank<=nronos) && ( rank >= 0)){
    printf("\n\n----------__________---------- ordem e rank respectivos: %d", rank);


    FILE* fp = fopen("prhases.txt","rb");
    if(fp == NULL) printf("isso n deveria estar aoarecendo");
    //=============aloca o dicionario e os vetores de palavras de tamanho fixo=====No mestre===
    dicionario = (char*)malloc( tamanhodicionario*(sizeof(char)) );
    int m = 0;
    duas = (vetorletra*)malloc( 26*(sizeof(vetorletra)) );
    if( duas == NULL)
      printf("erro na primeira alocacao de duas");
    for( m = 0; m < 26; m++){
      duas[m].letra = (char*)malloc( 200000*(sizeof(char)) );//o tamanho de 200000 foi escolhido pois supomos que cada tamanho de palavra nao ultrapassaria 5 mega bytes
      duas[m].tamanho = 0;
      if( duas[m].letra == NULL)
        printf("erro na segunda alocacao de duas");
    }
    tres = (vetorletra*)malloc( 26*(sizeof(vetorletra)) );
    for( m = 0; m < 26; m++){
      tres[m].letra = (char*)malloc( 200000*(sizeof(char)) );
      tres[m].tamanho = 0;
    }
    quatro = (vetorletra*)malloc( 26*(sizeof(vetorletra)) );
    for( m = 0; m < 26; m++){
      quatro[m].letra = (char*)malloc( 200000*(sizeof(char)) );
      quatro[m].tamanho = 0;
    }
    cinco = (vetorletra*)malloc( 26*(sizeof(vetorletra)) );
    for( m = 0; m < 26; m++){
      cinco[m].letra = (char*)malloc( 200000*(sizeof(char)) );
      cinco[m].tamanho = 0;
    }
    //======================================================================================

    //=====filtra arquivo e aloca os vetores de 2,3,4 e 5 porem nao em ordem alfabetica=====
    if( dicionario  == NULL){
      printf("\nnao conseguiu alocar a memoria desejada\n");
    }
    char* pequena = (char*)malloc( 1000*(sizeof(char)) );//representa a string lida do arquivo q sera colocada em um dos 26 vetores
    copia = (char*) malloc( (1000)*(sizeof(char)) );
    int lim = 0;//lim eh o tamanho da string que esta sendo lida do arquivo, e eh usada nas comparacoes  para verificar em qual a string deve entrar dado esse tamanho de lim
    nroletras = 0;
    int k = 0;
    int kquatro = 0;
    int kcinco = 0;
    int indletra = 0;// representa o a posicao no alfabeto da primeira letra de uma string - serve para a ordenacao que
    //fizemos usando este numero como indice do vetor vetorletra, pois assim cada letra fica em sua respectiva posicao, diminuindo o tempo de busca

    if(rank == 0){//somente o no mestre faz esta parte pois neste trecho as strings sao colocados nos vetores a
    do{//partir de suas letra inicias, ou seja, palavra com "a" ficam na posicao zero, comecando com "b" ficam na posicao 1, com "c" ficam na 2 e assim sucessivamente
        fread(&letra,sizeof(char),1,fp);//fica com nroletras sendo essa a quantidade total incluindo o \0
        if( ((letra > 96) && (letra < 123)) || (letra == 44) ){//strings com espacos sao tradadas como strings maiores pois concatena-se ignoram-se os espacos na hora de gerar a string seguinte
          pequena[nroletras] = letra;
          nroletras++;
          if( letra == 44){
            pequena[nroletras - 1] = '\0';//cria uma string com isso, pois antes tinha-se apenas um vetor de chars
            lim = strlen(pequena);
            if( (lim >  1) && (lim < 6) ){
             if(!procuradicionario(dicionario,pequena,copia,indicedicionario) ){//procura pela palavra numa string que contem todas as palavras lidas nao repetidas, e caso seja encontrada ela eh adicionada
              adicionanodicionario(dicionario,pequena,&indicedicionario);//com esta funcao, mas caso seja encontrada nao eh colocada em um dos 26 vetores pois assom filtramos as palavras repetidas
              numpal++;//contam quantas palavras tem-se ao todo
              indletra = ( ((int) pequena[0] ) - 97 )%26;//pega qual a letra do alfabeto
              if(lim == 2){
                  for(k = 0; k < lim + 1; k++,duas[indletra].tamanho++){//rcebe ateh o barra zero
                    duas[indletra].letra[duas[indletra].tamanho]= pequena[k];
                  }
              }
              if(lim == 3){
                  for(k = 0; k < lim + 1; k++,tres[indletra].tamanho++){//rcebe ateh o barra zero
                    tres[indletra].letra[tres[indletra].tamanho]= pequena[k];
                  }
              }
               if(lim == 4){
                  for(k = 0; k < lim + 1; k++,quatro[indletra].tamanho++){//rcebe ateh o barra zero
                    quatro[indletra].letra[quatro[indletra].tamanho]= pequena[k];
                  }
              }
               if(lim == 5){
                  for(k = 0; k < lim + 1; k++,cinco[indletra].tamanho++){//rcebe ateh o barra zero
                    cinco[indletra].letra[cinco[indletra].tamanho]= pequena[k];
                  }
              }
              }
             }
            nroletras = 0;//nroletras zera pois depois de colocar essa de dois deve-se recomecar a pequena string
            }
        }
    }while( ( !feof(fp) ) );
    }//fim do trecho de filtragem do no mestre, e o dicionario nao precisara ser usado pelo restante
    //========================================================

    //======geracao da string aletoria de tamanho mil e dos passeios======
      palavra = malloc( (1000)*(sizeof(char)) );// como a frase sempre eh grande e n existe palavra maior q mil entao coloquei esse tamanho arbitrariamente
      char* aleatoria = (char*)malloc( (1000)*(sizeof(char)) );//eh a string de tamanho 1000 q he gerada aleatoriamente para que possa-se caminhar checando de dois em dois ou tres em tres e assim por diante ateh cinco
      char* minialeatoriaduas = (char*)malloc( 3*sizeof(char));//
      char* minialeatoriatres = (char*)malloc( 4*sizeof(char));
      char* minialeatoriaquatro = (char*)malloc( 5*sizeof(char));
      char* minialeatoriacinco = (char*)malloc( 6*sizeof(char));
      char* miniletra = (char*)malloc(6*sizeof(char));//nao precisa ser mais q 6 pois a maior string para comparacao eh de tamanho 6
      subfrase = malloc( (1000)*(sizeof(char)) );
      srand ( time(NULL) );
      tamstring = 0;
      letrafrase = '0';//inicializacao basica
      base = 0;//variavel para percorrer a string aleatoria de mil posicoes
      int c = 0;//variavel de loop
      indletra = 0;
      int somatotal = 0;


      if(rank == 0 ){//envia o vetor de strings para tamanho dois para o no de rank,  o vetor de strings de tamanho 3 para o rank 2, e assim sucessivamente

        for(k=0; k<26;k++){
          MPI_Send( &(duas[k].tamanho), 1, MPI_INT, 1, tag = k,MPI_COMM_WORLD);//o no um fica sendo q faz o passeio de duas letras e assim por diante
          MPI_Send( duas[k].letra, duas[k].tamanho, MPI_CHAR, 1, tag = 26 + k,MPI_COMM_WORLD);
        }
        for(k=0; k<26;k++){
          MPI_Send( &(tres[k].tamanho), 1, MPI_INT, 2, tag = k,MPI_COMM_WORLD);//o no um fica sendo q faz o passeio de duas letras e assim por diante
          MPI_Send( tres[k].letra, tres[k].tamanho, MPI_CHAR, 2, tag = 26 + k,MPI_COMM_WORLD);
        }
        for(k=0; k<26;k++){
          MPI_Send( &(quatro[k].tamanho), 1, MPI_INT, 3, tag = k,MPI_COMM_WORLD);//o no um fica sendo q faz o passeio de duas letras e assim por diante
          MPI_Send( quatro[k].letra, quatro[k].tamanho, MPI_CHAR, 3, tag = 26 + k,MPI_COMM_WORLD);
        }
        for(k=0; k<26;k++){
          MPI_Send( &(cinco[k].tamanho), 1, MPI_INT, 4, tag = k,MPI_COMM_WORLD);//o no um fica sendo q faz o passeio de duas letras e assim por diante
          MPI_Send( cinco[k].letra, cinco[k].tamanho, MPI_CHAR, 4, tag = 26 + k,MPI_COMM_WORLD);
        }

      }


      if(rank == 1){

      for(k=0;k<26;k++){//recebe o vetor de strings de tamanho dois, e para os casos de tamanho tres quatro e cinco eh feito exatamente o mesmo procedimento, por isso nao havera cometarios
        MPI_Recv( &(duas[k].tamanho),1,MPI_INT,0,tag=k,MPI_COMM_WORLD,&stat);
        MPI_Recv( (duas[k].letra),duas[k].tamanho,MPI_CHAR,0,tag = k + 26 ,MPI_COMM_WORLD,&stat);
      }

      nropalavrasduas = 0;
      for(k=0; k<26; k++){
        nropalavrasduas = nropalavrasduas + duas[k].tamanho;//acumula as letras para depois dividr por tres ( duas letras mais o \0)
      }
      printf("\nnropalavrasduas: %d %d",nropalavrasduas,(nropalavrasduas/3) );
      nropalavrasduas = nropalavrasduas/3;
      do{
        for(k=0;k<1000;k++){//gera a string de tamanho 1000, e esse tamanho foi escolhido arbitrariamente
          ascii = (rand() % 26) + 97;
          aleatoria[k] = (char)ascii;
        }
        if( nropalavrasduas > 0){
          base = 0;
          do{//este trecho caminha de tres em tres ( duas letras mais o \0 ) ateh ou uma palvra ser encontrada ou o tamanho maximo ser atingido e assim precisar gerar uma nova string aleatoria
            minialeatoriaduas[0] = aleatoria[base];
            minialeatoriaduas[1] = aleatoria[base + 1];
            minialeatoriaduas[2] = '\0';
            indletra = ( ((int) aleatoria[base] ) - 97 )%26;
            for(c = 0; c < duas[indletra].tamanho; c = c + 3){//tem q se c = c + 3 pois anda uma string inteira por vez e nao pode ser menos pois se nao nao estaria annalisando palavras do texto
               miniletra[0] = duas[indletra].letra[c];//caminha no vetor cuja letra inicial eh a mesma verificando se a string aleatoria eh igual a alguma das palavras do vetor
               miniletra[1] = duas[indletra].letra[c+1];
               miniletra[2] = duas[indletra].letra[c+2];
               if( strcmp(minialeatoriaduas,miniletra) == 0){//compara se sao iguais, caso sim coloca caracteres que nao sao do alfabeto e sai do for, e caso naocontinua o for ateh encontrar uma igual ou chegar no tamanho maximo do for
                 //printf("\npalavra encontrada %s", miniletra);
                 duas[indletra].letra[c] = '-';
                 duas[indletra].letra[c+1] = '-';
                 duas[indletra].letra[c+2] = '\0';
                 nropalavrasduas--;//diminui o numero de palavras que serve para saber qndo o loop do passeio aleatorio que tenta gerar todas as strings de tamnaho dois termina
                 c = duas[indletra].tamanho;//condicao para sair do laco
               }
            }
            base++;
          }while( (nropalavrasduas > 0) && (base < 998) );//tomar cuidado na hora de replicar com essa linhas e qq otra haver com a base
        }
      }while( nropalavrasduas > 0 );
      }



      if(rank == 2){//conforme citado acima este trecho nao eh comentado

      for(k=0;k<26;k++){
        MPI_Recv( &(tres[k].tamanho),1,MPI_INT,0,tag=k,MPI_COMM_WORLD,&stat);
        MPI_Recv((tres[k].letra),tres[k].tamanho,MPI_CHAR,0,tag = k + 26 ,MPI_COMM_WORLD,&stat);
      }

      base = 0;
      c = 0;
      indletra = 0;
      somatotal = 0;

      nropalavrastres = 0;
      for(k=0; k<26; k++){
        nropalavrastres = nropalavrastres + tres[k].tamanho;//nrototal de
      }
      printf("\nnropalavrastres: %d %d",nropalavrastres,(nropalavrastres/4) );
      nropalavrastres = nropalavrastres/4;
      do{
        for(k=0;k<1000;k++){
          ascii = (rand() % 26) + 97;
          aleatoria[k] = (char)ascii;
        }
        if( nropalavrastres > 0){
          base = 0;
          do{
            minialeatoriatres[0] = aleatoria[base];
            minialeatoriatres[1] = aleatoria[base + 1];
            minialeatoriatres[2] = aleatoria[base + 2];
            minialeatoriatres[3] = '\0';
            indletra = ( ((int) aleatoria[base] ) - 97 )%26;
            for(c = 0; c < tres[indletra].tamanho; c = c + 4){
               miniletra[0] = tres[indletra].letra[c];
               miniletra[1] = tres[indletra].letra[c+1];
               miniletra[2] = tres[indletra].letra[c+2];
               miniletra[3] = tres[indletra].letra[c+3];
               if( strcmp(minialeatoriatres,miniletra) == 0){
                 //printf("\npalavra encontrada %s", miniletra);
                 contadortres++;//caumenta o numero de palavras para mandar mensagem avisando que 100 palavras foram geradas
                 if(contadortres == 100){
                   MPI_Send( &contadortres, 1, MPI_INT, 0, tag = 1,MPI_COMM_WORLD);
                   contadortres = 0;
                 }
                 tres[indletra].letra[c] = '-';
                 tres[indletra].letra[c+1] = '-';
                 tres[indletra].letra[c+2] = '-';
                 tres[indletra].letra[c+3] = '\0';
                 nropalavrastres--;
                 c = tres[indletra].tamanho;//acho q eh equivalente a break
               }
            }
            base++;
            //printf(" %d",base);
          }while( (nropalavrastres > 0) && (base < 997) );//tomar cuidado na hora de replicar com essa linhas e qq otra haver com a base
        }
      }while( nropalavrastres > 0 );
      }


      if(rank == 3){//mesmo caso do rank dois, porem para strings de tamanho quatro
      for(k=0;k<26;k++){
        MPI_Recv(&(quatro[k].tamanho),1,MPI_INT,0,tag=k,MPI_COMM_WORLD,&stat);
        MPI_Recv((quatro[k].letra),quatro[k].tamanho,MPI_CHAR,0,tag = k + 26 ,MPI_COMM_WORLD,&stat);
      }


      base = 0;
      c = 0;
      indletra = 0;
      somatotal = 0;

      nropalavrasquatro = 0;

      for(k=0; k<26; k++){
        nropalavrasquatro = nropalavrasquatro + quatro[k].tamanho;//nrototal de
      }
      printf("\nnropalavrasquatro: %d %d",nropalavrasquatro,(nropalavrasquatro/5));
      nropalavrasquatro = nropalavrasquatro/5;
      do{
        for(k=0;k<1000;k++){
          ascii = (rand() % 26) + 97;
          aleatoria[k] = (char)ascii;
        }
        if( nropalavrasquatro > 0){
          base = 0;
          do{
            minialeatoriaquatro[0] = aleatoria[base];
            minialeatoriaquatro[1] = aleatoria[base + 1];
            minialeatoriaquatro[2] = aleatoria[base + 2];
            minialeatoriaquatro[3] = aleatoria[base + 3];
            minialeatoriaquatro[4] = '\0';
            indletra = ( ((int) aleatoria[base] ) - 97 )%26;
            for(c = 0; c < quatro[indletra].tamanho; c = c + 5){
               miniletra[0] = quatro[indletra].letra[c];
               miniletra[1] = quatro[indletra].letra[c+1];
               miniletra[2] = quatro[indletra].letra[c+2];
               miniletra[3] = quatro[indletra].letra[c+3];
               miniletra[4] = quatro[indletra].letra[c+4];
               if( strcmp(minialeatoriaquatro,miniletra) == 0){
                 //printf("\npalavra encontrada %s com porcentagem %d", miniletra, (nropalavrasquatro/((quatro[indletra].tamanho)/5)) );
                 contadorquatro++;
                 if(contadorquatro == 100){
                   MPI_Send( &contadorquatro, 1, MPI_INT, 0, tag = 1,MPI_COMM_WORLD);
                   contadorquatro = 0;
                 }
                 quatro[indletra].letra[c] = '-';
                 quatro[indletra].letra[c+1] = '-';
                 quatro[indletra].letra[c+2] = '-';
                 quatro[indletra].letra[c+3] = '-';
                 quatro[indletra].letra[c+4] = '\0';
                 nropalavrasquatro--;
                 c = quatro[indletra].tamanho;//acho q eh equivalente a break
               }
            }
            base++;
            //printf(" %d",base);
          }while( (nropalavrasquatro > 0) && (base < 996) );//tomar cuidado na hora de replicar com essa linhas e qq otra haver com a base
        }
      }while( nropalavrasquatro > 0 );
      }


      if(rank == 4){//mesmo caso do rank 3 porem para string de tamanho cinco
      for(k=0;k<26;k++){
        MPI_Recv(&(cinco[k].tamanho),1,MPI_INT,0,tag=k,MPI_COMM_WORLD,&stat);
        MPI_Recv((cinco[k].letra),cinco[k].tamanho,MPI_CHAR,0,tag = k + 26 ,MPI_COMM_WORLD,&stat);
      }


      base = 0;
      c = 0;
      indletra = 0;
      somatotal = 0;

      nropalavrascinco = 0;
      for(k=0; k<26; k++){
        nropalavrascinco = nropalavrascinco + cinco[k].tamanho;//nrototal de
      }
      printf("\nnropalavrascinco: %d %d",nropalavrascinco,(nropalavrascinco/6) );
      nropalavrascinco = nropalavrascinco/6;
      do{
        for(k=0;k<1000;k++){
          ascii = (rand() % 26) + 97;
          aleatoria[k] = (char)ascii;
        }
        if( nropalavrascinco > 0){
          base = 0;
          do{
            minialeatoriacinco[0] = aleatoria[base];
            minialeatoriacinco[1] = aleatoria[base + 1];
            minialeatoriacinco[2] = aleatoria[base + 2];
            minialeatoriacinco[3] = aleatoria[base + 3];
            minialeatoriacinco[4] = aleatoria[base + 4];
            minialeatoriacinco[5] = '\0';
            indletra = ( ((int) aleatoria[base] ) - 97 )%26;
            for(c = 0; c < cinco[indletra].tamanho; c = c + 6){
               miniletra[0] = cinco[indletra].letra[c];
               miniletra[1] = cinco[indletra].letra[c+1];
               miniletra[2] = cinco[indletra].letra[c+2];
               miniletra[3] = cinco[indletra].letra[c+3];
               miniletra[4] = cinco[indletra].letra[c+4];
               miniletra[5] = cinco[indletra].letra[c+5];
               if( strcmp(minialeatoriacinco,miniletra) == 0){
                 //printf("\npalavra encontrada %s com porcentagem %d", miniletra, (nropalavrascinco/((cinco[indletra].tamanho)/6)) );
                 contadorcinco++;
                 if(contadorcinco == 100){
                   MPI_Send( &contadorcinco, 1, MPI_INT, 0, tag = 1,MPI_COMM_WORLD);//colocamos um para poder receber de qualquer um
                   contadorcinco = 0;
                 }
                 cinco[indletra].letra[c] = '-';
                 cinco[indletra].letra[c+1] = '-';
                 cinco[indletra].letra[c+2] = '-';
                 cinco[indletra].letra[c+3] = '-';
                 cinco[indletra].letra[c+4] = '-';
                 cinco[indletra].letra[c+5] = '\0';
                 nropalavrascinco--;
                 c = cinco[indletra].tamanho;//acho q eh equivalente a break
               }
            }
            base++;
            //printf(" %d",base);
          }while( (nropalavrascinco > 0) && (base < 995) );//tomar cuidado na hora de replicar com essa linhas e qq otra haver com a base
        }
      }while( nropalavrascinco > 0 );
      }
    //este trecho calcula quantas palavras foram geradas recebendo as informacoes dos nos escravos

    if(rank == 0){
    printf("\nnrototal de palavras %d", numpal);
    while( ((double)aux) /((double)numpal)  <= 0.8){
        MPI_Recv(&cont123,1,MPI_INT,MPI_ANY_SOURCE,tag = 1 ,MPI_COMM_WORLD,&stat);
        aux = aux + cont123;
        if( ((double)aux) /((double)numpal)  >= flag*0.2){
            gettimeofday(&tvMarco, NULL);
            switch(flag){
                case 1:
                    timeval_subtract(&porcent20, &tvMarco, &tvBegin);
                    printf("20% = %lf\n", porcent20);
                    flag++;
                    break;
                case 2:
                    timeval_subtract(&porcent40, &tvMarco, &tvBegin);
                    printf("40% = %lf\n", porcent40);
                    flag++;
                    break;
                case 3:
                    timeval_subtract(&porcent60, &tvMarco, &tvBegin);
                    printf("60% = %lf\n", porcent60);
                    flag++;
                    break;
                case 4:
                    timeval_subtract(&porcent80, &tvMarco, &tvBegin);
                    printf("80% = %lf\n", porcent80);
                    flag++;
                    break;
            }
        }
      }//fecha o while
    }//fecha a protecao de rank
    if( ( ((double)aux) /((double)numpal)  >= 0.85)  && ( ((double)aux) /((double)numpal)  <= 0.90)){
            timeval_subtract(&porcent85, &tvMarco, &tvBegin);
            printf("entre 85 e 90% = %lf\n", porcent85);
        }
    MPI_Barrier(MPI_COMM_WORLD);
    timeval_subtract(&porcent100, &tvMarco, &tvBegin);
    printf("100% = %lf\n", porcent100);
    /*
    printf("\n");
    printf("Tempo de encontrar porcentagem aproximada de palavras:\n");
    printf("20% = %lf\n", porcent20);
    printf("40% = %lf\n", porcent40);
    printf("60% = %lf\n", porcent60);
    printf("80% = %lf\n", porcent80);
    printf("100% = %lf\n", porcent100);
    */
    fclose(fp);
    }//fecha o que protegeu por rank
    MPI_Finalize();
    return 0;

}

int adicionanodicionario( char* dicionario, char* str, int* indicedicionario){

  int indpalavra = 0;
  for ( indpalavra = 0; indpalavra < strlen(str) + 1; indpalavra++, (*indicedicionario)++){//vai ateh strlen mais um para poder pegar o \0
    dicionario[(*indicedicionario)] = str[indpalavra];
  }//como o for incrementa na ultima iteracao, logo o valor jah sai no local certo
  return 0;

}


int procuradicionario( char* dicionario, char* str, char* copia,int indiceatual){

  int indpalavra = 0;
  int cpyindicedicionario = 0;
  int interrompe  = 0;
  int lim = strlen(dicionario);
  while( (cpyindicedicionario < indiceatual) && (interrompe == 0) ) {//varre o dicionario com o indice de baixo
    indpalavra = 0;
    while (  ((dicionario[cpyindicedicionario] != '\0') && ( cpyindicedicionario < indiceatual)) && (interrompe == 0) ){//como dicionario tem varios \0
      copia[indpalavra] = dicionario[cpyindicedicionario];//copia eh alocado no principal com o mesmo tamanho de uma palavra
      indpalavra++;
      cpyindicedicionario++;
    }
    cpyindicedicionario++;//para pular o \0
    copia[indpalavra] = '\0';
    if( strcmp(copia,str) == 0 ){
      interrompe = 1;
      //printf("\n==__== a palavra %s foi otimizada ==__== %d",str,interrompe);
      return interrompe;
    }
  }
  return interrompe;
}

//nao eh utilizado
int tempalavaras(char* frase){

  int i = 0;
  for(i = 0; i < strlen(frase); i++){
    if( (frase[i] > 96) && (frase[i] <123) ){
      return 1;
    }
  }
  return 0 ;
}

int timeval_subtract(double* result, struct timeval *t2, struct timeval *t1)
{
    double tempototal = (((double)(t2->tv_usec - t1->tv_usec))/1000000) +  (t2->tv_sec - t1->tv_sec);
    (*result) = tempototal;
    return 0;
}





